#define C00 vec3(0.1,0.2,0.4)
#define C01 vec3(0.2,0.3,0.5)
#define C02 vec3(0.4,0.4,0.4)
#define C03 vec3(0.0,0.1,0.2)

#define C10 vec3(0.5,0.6,0.7)
#define C11 vec3(1.3,0.85,0.5)
#define C12 vec3(0.6,0.6,0.6)
#define C13 vec3(0.1,0.2,0.4)

#define StwiDist vec2(0.8,0.8)
#define StwiColr vec3(0.6,1.0,1.5)

//数学
float pow2(float x) {return x * x;}
vec2 pow2(vec2 x) {return x * x;}
vec3 pow2(vec3 x) {return x * x;}
vec4 pow2(vec4 x) {return x * x;}
float pow3(float x) {return x * x * x;}
vec2 pow3(vec2 x) {return x * x * x;}
vec3 pow3(vec3 x) {return x * x * x;}
vec4 pow3(vec4 x) {return x * x * x;}
float pow4(float x) {x = x * x; return x * x;}
vec2 pow4(vec2 x) {x = x * x; return x * x;}
vec3 pow4(vec3 x) {x = x * x; return x * x;}
vec4 pow4(vec4 x) {x = x * x; return x * x;}
float pow5(float x) {float x2 = x * x; return x2 * x2 * x;}
vec2 pow5(vec2 x) {vec2 x2 = x * x; return x2 * x2 * x;}
vec3 pow5(vec3 x) {vec3 x2 = x * x; return x2 * x2 * x;}
vec4 pow5(vec4 x) {x = x * x; x = x * x; return x * x;}
float pow8(float x) { x = x * x; x = x * x; return x * x;}
vec2 pow8(vec2 x) {x = x * x; x = x * x; return x * x;}
vec3 pow8(vec3 x) {x = x * x; x = x * x; return x * x;}
vec4 pow8(vec4 x) {x = x * x; x = x * x; return x * x;}
float clamp2(float x){return min( max( x, 0.0 ), 1.0 ); }
vec2 clamp2(vec2 x){ return min( max( x, vec2(0,0) ), vec2(1,1) );}
vec3 clamp2(vec3 x){return min( max( x, vec3(0.0,0.0,0.0) ), vec3(1.0,1.0,1.0) );}
float StweightHash21(vec2 p) {float r = fract(43757.5453 * sin(dot(p, vec2(12.9898, 78.233))));return r;}

//色调映射
vec3 ACESToneMapping(vec3 color, float adapted_lum){
    const float A = 2.51;
	const float B = 0.03;
	const float C = 2.43;
	const float D = 0.59;
	const float E = 0.14;
	color *= adapted_lum;
	return (color * (A * color + B)) / (color * (C * color + D) + E);}

vec3 FilmToneMapping(vec3 color){
	color = max(vec3(0.0, 0.0, 0.0), color - vec3(0.1, 0.1, 0.1));
	color = (color * (6.6 * color + 0.3)) / (color * (5.0 * color + 2.6) + 0.35);
	return color;
}

vec3 StweightLaugen(vec3 lightpos, vec3 skypos, vec3 x){
	vec2 MapSet = floor(abs(skypos.xz)*400.0)/400.0;
	float StweNoise = StweightHash21(MapSet);
    float Hight = skypos.y;
    vec3 Stweight = StwiColr;
	StweNoise *= pow2(StweightHash21(MapSet+StwiDist));
	Stweight *= saturate(StweNoise-0.85);
	Stweight *= mix(0.0,1.0,smoothstep(0.0,1.5,Hight));
	return Stweight*20.0;
}

float DisegnaIlSole(vec3 p){
    return inversesqrt(pow2(p.x) + pow2(p.y) + pow2(p.z));
}

vec3 EnderCaelo(vec3 colar, vec3 wpos, vec3 SunPos){
    float Sol = DisegnaIlSole(cross(wpos*0.07, SunPos));
    vec3 pos = normalize(vec3(wpos.x, wpos.y, wpos.z));
    float Skylusor01 = max(1.0-length(wpos.xz / (wpos.y))*0.1, 0.0);                               
    vec3 RcielocolorUniform = vec3(0.0, -0.2, 0.2);
    vec3 RciellcolorUniform = vec3(0.25, 0.1, 0.45);
    colar = RcielocolorUniform;
    colar = mix(colar, vec3(1.0, 1.0, 1.0), Sol * (wpos.y > 0.0 ? 1.0 : 0.0));
    colar = mix( RciellcolorUniform,colar,smoothstep(0.0, 1.0, pow4(Skylusor01)));
    colar += mix(StweightLaugen(vec3(0.0, 0.0, 0.0), normalize(wpos), vec3(0.0, 0.0, 0.0)),vec3(0.0, 0.0, 0.0), SunPos.y);
    return colar;
}

vec3 EnderNebula(vec3 colar, vec3 wpos){
    float Skylusor01 = max(1.0-length(wpos.xz / (wpos.y))*0.1, 0.0);                             
    vec3 RcielocolorUniform = vec3(0.0, -0.2, 0.2);
    vec3 RciellcolorUniform = vec3(0.25, 0.1, 0.45);
    colar = RcielocolorUniform;
    colar = mix( RciellcolorUniform,colar,smoothstep(0.0, 1.0, pow(Skylusor01,4.5)));
    return colar;
}

vec3 CaeloBasic(float llover, vec3 color_nebula){
    float no=pow(max(min(1.-color_nebula.r*1.5,1.0),0.0),1.2);
    float ta=pow(max(min(1.-color_nebula.b*1.5,1.0),0.0),0.5);
    vec3 colorbase = mix(mix( C00, C01, ta ), C03, no );
    return mix(colorbase, C02, llover);
}

vec3 CaeloHorizionte(float llover, vec3 color_nebula){
    float no=pow(max(min(1.-color_nebula.r*1.5,1.0),0.0),1.2);
    float ta=pow(max(min(1.-color_nebula.b*1.5,1.0),0.0),0.5);
    vec3 colorbase = mix(mix( C10, C11, ta ), C13, no );
    return mix(colorbase, C12, llover);
}

vec3 ColorNubis(float llover, vec3 color_nebula){
    float no=pow(max(min(1.-color_nebula.r*1.5,1.0),0.0),1.2);
    float ta=pow(max(min(1.-color_nebula.b*1.5,1.0),0.0),0.5);
    vec3 colorbase = mix(mix( vec3(1.2,1.1,1.0), vec3(1.3,1.0,0.7), ta ), vec3(0.2,0.2,0.2), no );
    return mix(colorbase, vec3(0.6,0.6,0.6), llover);
}

vec3 AquoBasic(float llover, vec3 color_nebula){
    float no=pow(max(min(1.-color_nebula.r*1.5,1.0),0.0),1.2);
    float ta=pow(max(min(1.-color_nebula.b*1.5,1.0),0.0),0.5);
    vec3 colorbase = mix(mix( vec3(0.0,0.1,0.4), vec3(0.0,0.2,0.7), ta ), vec3(0.0,0.15,0.2), no );
    return mix(colorbase, vec3(0.3,0.3,0.3), llover);
}

vec3 Ambient(float llover, vec3 color_nebula){
    float no=pow(max(min(1.-color_nebula.r*1.5,1.0),0.0),1.2);
    float ta=pow(max(min(1.-color_nebula.b*1.5,1.0),0.0),0.5);
    vec3 colorbase = mix(mix( vec3(2.0,1.8,1.6), vec3(1.5,1.2,0.9), ta ), vec3(0.8,1.1,1.5), no );
    return mix(colorbase, vec3(1.0,1.0,1.0), llover);
}
float AlfaNubis(float llover, vec3 color_nebula){
    float no=pow(max(min(1.-color_nebula.r*1.5,1.0),0.0),1.2);
    float ta=pow(max(min(1.-color_nebula.b*1.5,1.0),0.0),0.5);
    float data = mix(mix( 0.03, 0.03, ta ), 0.01, no );
    return mix(data, 0.0, llover);
}

vec3 CaeloFinal(vec3 base, vec3 horizion, float pos_y){
    return mix(base,horizion,pos_y);
}

float ViaALlover(vec3 fograndfarnear) {
    vec2 function = clamp((fograndfarnear.xy - vec2(0.5 + 20.0 / fograndfarnear.z, 1.0)) / (vec2(0.23, 0.70) - vec2(0.5 + 20.0 / fograndfarnear.z, 1.0)), vec2(0.0, 0.0),vec2(1.0, 1.0));
    return pow2((function.x * function.y)) * (3.0 - 2.0 * (function.x * function.y));
}